package com.roc.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.roc.bean.TblJumpMchtInf;
import com.roc.dao.ISQLBaseDao;
import com.roc.pojo.Operators;
import com.roc.service.JumpMchtService;
import com.roc.service.ServiceException;
import com.roc.util.CheckIdCard;
import com.roc.util.Constance;
import com.roc.util.HttpUtil;
import com.roc.util.Utils;
import com.roc.util.constant.MccGroup;

@Service
public class JumpMchtServiceImpl implements JumpMchtService{
	
	private Logger logger = LogManager.getLogger(JumpMchtServiceImpl.class);
	
	@Autowired
	private ISQLBaseDao sqlBaseDao;
	
	@Transactional(readOnly=true)
	@Override
	public TblJumpMchtInf queryJumpMchtDetail(String mchtCd) throws ServiceException {
		String sql = "select t.mcht_cd,t.name_busi,a.mcc_group,a.status from tbl_mcht_inf t left join "
				+ " apstfr.tbl_jump_mcht_inf a on t.mcht_cd=a.mcht_cd where t.mcht_cd=? ";
		TblJumpMchtInf tjm = new TblJumpMchtInf();
		try {
			Object obj = sqlBaseDao.findObj(sql, new Object[]{mchtCd});
			Object[] objs = (Object[]) obj;
			
			if(objs != null){
				tjm.setMchtCd(Constance.Null2EmptyTrim(objs[0]));
				tjm.setMerName(Constance.Null2EmptyTrim(objs[1]));
				tjm.setMccGroup(Constance.Null2EmptyTrim(objs[2]));
				tjm.setStatus(Constance.Null2EmptyTrim(objs[3]));
				tjm.setMccGroupName(MccGroup.getName((Constance
						.Null2EmptyTrim(objs[2]))));
			}
			
		} catch (Exception e) {
//			e.printStackTrace();
			logger.error("查询自选商户开通详情异常：",e);
			throw new ServiceException("查询自选商户开通详情异常",e);
		}
		
		return tjm;
		
	}
	
	@Transactional(rollbackFor = { ServiceException.class })
	@Override
	public Map<String,Object> saveOrUpdateJumpMchtInf(TblJumpMchtInf tjm,Operators logingMerchant) throws ServiceException {
		 
		Map<String,Object> resMap = new HashMap<String, Object>();
		resMap.put("flag", true);
		List<Object> paramsList = new ArrayList<Object>();
		try {
			
			String mchtCd = Constance.Null2EmptyTrim(tjm.getMchtCd());
			String newMccCd = Constance.Null2EmptyTrim(tjm.getNewMccCd());
			
			if("".equals(mchtCd)){
				resMap.put("msg", "商户号为空");
				return resMap;
			}
			
			if("".equals(newMccCd)){
				resMap.put("msg", "新的类别码为空");
				return resMap;
			}
			
			String selProvCd = "select t.prov_no from apstfr.tbl_area_unionpay_inf t where t.area_no in (select substr(tt.uc_bc_cd_32,5,4) from apstfr.tbl_mcht_inf tt where tt.mcht_cd =?)";
			Object provCdObj = sqlBaseDao.findObj(selProvCd, new Object[]{mchtCd}); 
			
			logger.info("商户【"+mchtCd+"】银联省为：【"+String.valueOf(provCdObj)+"】");
			
			String selCanUsedMchtCountSql = "select count(1) from apstfr.tbl_route_mcht_inf t where t.prov_cd =?  and t.status =? and t.mcc_group =?";
			Object selCanUsedMchtCountObj = sqlBaseDao.findObj(selCanUsedMchtCountSql, new Object[]{provCdObj,"1",newMccCd});
			if(selCanUsedMchtCountObj != null){
				int selCanUsedMchtCount = Integer.parseInt(String.valueOf(selCanUsedMchtCountObj));
				logger.info("商户【"+mchtCd+"】转换类型【"+newMccCd+"】，可用商户数为：【"+selCanUsedMchtCount+"】");
				if(selCanUsedMchtCount<1){
					resMap.put("msg", "无可用商户");
					return resMap;
				}
			}else{
				logger.info("商户【"+mchtCd+"】转换类型【"+newMccCd+"】，可用商户数为：【"+String.valueOf(selCanUsedMchtCountObj)+"】");
				resMap.put("msg", "无可用商户");
				return resMap;
			}
			
			//查询商户信息
			String selMchtSql = " select a.mcht_cd,a.k2workflowid,a.certif_no,b.account,b.name,a.DVP_BY,a.STLM_WAY_DESC "
					+ " from tbl_mcht_inf a,tbl_mcht_bankaccount b "
					+ " where a.mcht_cd=b.owner_cd and b.accounttype='01' and a.status='01' and a.mcht_cd=? ";
			Object selMchtObj = sqlBaseDao.findObj(selMchtSql, new Object[]{mchtCd});
			if(selMchtObj==null){
				resMap.put("msg", "商户号【"+tjm.getMchtCd()+"】银行卡信息查询失败");
				return resMap;
			}
			Object[] selMchtObjArray = (Object[]) selMchtObj;
			
			String k2workflowid = Constance.Null2EmptyTrim(selMchtObjArray[1]);
			if("".equals(k2workflowid)){
				resMap.put("flag", false);
				resMap.put("msg", "该商户未进行银行卡验证");
				return resMap;
			}
			
			//DVP_BY	N	NVARCHAR2(50)	Y			发展人/推荐人 （ 0是  1否法人结算账户，若为否则需要非法人身份证号）
			//STLM_WAY_DESC	N	VARCHAR2(50)	Y			商户结算途径其它说明（非法人的身份证）
			String dvpBy = Constance.Null2EmptyTrim(selMchtObjArray[5]);
			String cardNo = Constance.Null2EmptyTrim(selMchtObjArray[2]);
			if("1".equals(dvpBy)){//非法人结算
				cardNo = Constance.Null2EmptyTrim(selMchtObjArray[6]);//证件号
			}
			
			//是否进行过四要素校验
			String selFourEleSql = "select 1 from t_wechat_validate t "
					    + " where t.phone_no=? and t.account_no=? and t.account_name=? and t.identity_card=? and t.open_id=? and t.remark='1' ";
			Object selObj = sqlBaseDao.findObj(selFourEleSql, new Object[]{
					k2workflowid,
					Constance.Null2EmptyTrim(selMchtObjArray[3]),
					Constance.Null2EmptyTrim(selMchtObjArray[4]),
					cardNo,
					Constance.Null2EmptyTrim(selMchtObjArray[0])
			});
			if(selObj == null){
				resMap.put("flag", false);
				resMap.put("msg", "该商户未进行银行卡验证");
				return resMap;
			}
			
			//查询自选商户开通信息
			String sql = "select t.MCHT_CD,to_char(t.REC_TM,'yyyyMMdd HH24miss'),t.status,t.mcc_group from apstfr.tbl_jump_mcht_inf t where t.mcht_cd=?";
			Object objArray = sqlBaseDao.findObj(sql, new Object[]{mchtCd});
			if(objArray != null){
				
				Object[] strArray  = (Object[])objArray;
				
				//判断是否关闭
				if("0".equals(String.valueOf(strArray[2])) && !"".equals(Constance.Null2EmptyTrim(strArray[3]))){
					resMap.put("msg", "功能未开启，请联系管理员");
					return resMap;
				}
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");
				long t1 = sdf.parse(String.valueOf(strArray[1])).getTime()+(2*60*60*1000);
				long t2 = new Date().getTime();
				if(t1 > t2 && !"".equals(Constance.Null2EmptyTrim(strArray[3]))){
					resMap.put("msg", "两小时内只能修改一次");
					return resMap;
				}
				
				logger.info(tjm.getMchtCd()+"在行业分类设置里已存在，执行修改操作开始，操作人："+logingMerchant.getAccountNo());
				paramsList.clear();
				paramsList.add(newMccCd);
				paramsList.add(new Date());
				paramsList.add(mchtCd);
				String updSql = "update apstfr.tbl_jump_mcht_inf t set t.MCC_GROUP=?,t.REC_TM=?,t.status='1' where t.mcht_cd=? ";
				int updCount = sqlBaseDao.deleteBySql(updSql, paramsList);
				if(updCount != 1){
					throw new ServiceException(tjm.getMchtCd()+"行业分类设置修改异常，操作人："+logingMerchant.getAccountNo());
				}
				logger.info(tjm.getMchtCd()+"行业分类设置修改成功，操作人："+logingMerchant.getAccountNo()+"修改后的值为：【"+tjm.getNewMccCd()+"】");
				
			}else{
				resMap.put("msg", "未查询到相关信息");
				return resMap;
			}
			
			
		} catch (Exception e) {
			logger.error("行业分类设置保存失败:"+e.getMessage());
			throw new ServiceException("行业分类设置保存失败");
		}
		resMap.put("msg", "操作成功");
		return resMap;
		
	}
	
	@Transactional(rollbackFor = { ServiceException.class })
	@Override
	public synchronized Map<String,Object> modifyPerfectBillStatus(String openMchtCd,String openStatus,Operators logingMerchant) throws ServiceException{
		Map<String,Object> resMap = new HashMap<String, Object>();
		resMap.put("flag", false);
		resMap.put("msg", "操作失败");
		
		List<Object> paramsList = new ArrayList<Object>();
		
		String mchtCd = Constance.Null2EmptyTrim(openMchtCd);
		
		if("".equals(mchtCd)){
			resMap.put("flag", false);
			resMap.put("msg", "商户号为空");
			return resMap;
			
		}
		
		//1开启0关闭
		if(!"0".equals(openStatus) && !"1".equals(openStatus) && !"".equals(openStatus)){
			logger.info("商户【"+mchtCd+"】状态标志位值错误");
			resMap.put("flag", false);
			resMap.put("msg", "开关异常，操作商户【"+mchtCd+"】失败");
			return resMap;
			
		}
		
		try {
			
			//开启需要进行银行卡验证，关闭不需要
			if(("0").equals(openStatus) || "".equals(openStatus)){//开启
				 //查询自选商户开通信息
				String sql = "select t.MCHT_CD,to_char(t.REC_TM,'yyyyMMdd HH24miss'),t.status,t.mcc_group from apstfr.tbl_jump_mcht_inf t where t.mcht_cd=?";
				
				Object objArray = sqlBaseDao.findObj(sql, new Object[]{mchtCd});
				
				if(objArray != null){
					String updJumpMchtSqlOpen = "";
					//更新状态
					Object[] jumpArray = (Object[]) objArray;
					String mccGroup = Constance.Null2EmptyTrim(jumpArray[3]);
					
					if(!"".equals(mccGroup)){
						updJumpMchtSqlOpen = "update apstfr.tbl_jump_mcht_inf t set t.REC_TM=?,t.status='1' where t.mcht_cd=? and t.status='0' ";

					}else{
						updJumpMchtSqlOpen = "update apstfr.tbl_jump_mcht_inf t set t.REC_TM=?,t.status='0' where t.mcht_cd=? and t.status='0' ";
					}
					
					logger.info(mchtCd+"在自选商户开通里已存在，执行修改操作开始，操作人："+logingMerchant.getAccountNo());
					paramsList.clear();
					paramsList.add(new Date());
					paramsList.add(mchtCd);
					int updCount = sqlBaseDao.deleteBySql(updJumpMchtSqlOpen, paramsList);
					if(updCount != 1){
						throw new ServiceException(mchtCd+"自选商户开通修改异常，操作人："+logingMerchant.getAccountNo());
					}
					logger.info(mchtCd+"自选商户开通修改成功，操作人："+logingMerchant.getAccountNo());
					
					
				}else{//不存在
					String insertSql = "insert into apstfr.tbl_jump_mcht_inf (MCHT_CD, MCC_GROUP, STATUS, REC_TM)"
							+ " values (?, ?, ?, ?)";
					
					logger.info(mchtCd+"在自选商户开通里不存在，执行新增操作开始，操作人："+logingMerchant.getAccountNo());
					paramsList.clear();
					paramsList.add(mchtCd);
					paramsList.add("");
					paramsList.add("0");
					paramsList.add(new Date());
					
					int insertCount = sqlBaseDao.deleteBySql(insertSql, paramsList);
					if(insertCount != 1){
						throw new ServiceException(mchtCd+"自选商户开通插入异常，操作人："+logingMerchant.getAccountNo());
					}
					logger.info(mchtCd+"自选商户开通插入成功，操作人："+logingMerchant.getAccountNo()+"插入的值为：【"+mchtCd+"】");
					
					//插入流水表数据
					String insertLogSql = "insert into tbl_jump_mcht_log (AGENTID, MCHT_CD, MCC, CRT_DATE) values (?, ?, ?, ?)";
					
					paramsList.clear();
					paramsList.add(logingMerchant.getId());
					paramsList.add(mchtCd);
					paramsList.add("");
					paramsList.add(new Date());
					int insertLogCount = sqlBaseDao.deleteBySql(insertLogSql, paramsList);
					if(insertLogCount != 1){
						throw new ServiceException(mchtCd+"自选商户开通流水插入失败，操作人："+logingMerchant.getAccountNo());
					}
					logger.info(mchtCd+"自选商户开通流水插入成功，操作人："+logingMerchant.getAccountNo()+"插入的值为：【"+mchtCd+"】");
					
					String insertModule = "insert into t_merchant_module values(MERCHANT_MODULE_seq.Nextval,'C_02_M_27','"+mchtCd+"',sysdate,sysdate,'administrator') ";
					
					int insertModuleCount = sqlBaseDao.deleteBySql(insertModule, null);
					if(insertModuleCount != 1){
						throw new ServiceException(mchtCd+"添加自选商户开通菜单失败，操作人："+logingMerchant.getAccountNo());
					}
				}
			}else{
				
				String updJumpMchtSqlClose = "update apstfr.tbl_jump_mcht_inf t set t.REC_TM=?,t.status='0' where t.mcht_cd=? and t.status='1' ";
				
				logger.info(mchtCd+"在自选商户开通里已存在，执行修改操作开始，操作人："+logingMerchant.getAccountNo());
				paramsList.clear();
				paramsList.add(new Date());
				paramsList.add(mchtCd);
				int updCount = sqlBaseDao.deleteBySql(updJumpMchtSqlClose, paramsList);
				if(updCount != 1){
					throw new ServiceException(mchtCd+"自选商户开通修改异常，操作人："+logingMerchant.getAccountNo());
				}
				logger.info(mchtCd+"自选商户开通修改成功，操作人："+logingMerchant.getAccountNo());
				
				
			}
			
			resMap.put("flag", true);
			resMap.put("msg", "操作成功");
			
		} catch (Exception e) {
			logger.error("商户【"+mchtCd+"】自选商户状态修改失败:",e);
			throw new ServiceException("商户【"+mchtCd+"】自选商户状态修改失败");
		}
		
		return resMap;
		
	}
	
	
	@Transactional(readOnly=true)
	@Override
	public TblJumpMchtInf queryFourEleDetail(String mchtCd) throws ServiceException {
		String sql = "select a.mcht_cd,b.name,b.account,b.bank_name,a.certif_no,a.DVP_BY,a.STLM_WAY_DESC "
				+ "from tbl_mcht_inf a,tbl_mcht_bankaccount b "
				+ "where a.mcht_cd=b.owner_cd and b.accounttype='01' and a.status='01' and a.mcht_cd=? ";
		TblJumpMchtInf tjm = new TblJumpMchtInf();
		try {
			Object obj = sqlBaseDao.findObj(sql, new Object[]{mchtCd});
			Object[] objs = (Object[]) obj;
			
			//DVP_BY	N	NVARCHAR2(50)	Y			发展人/推荐人 （ 0是  1否法人结算账户，若为否则需要非法人身份证号）
			//STLM_WAY_DESC	N	VARCHAR2(50)	Y			商户结算途径其它说明（非法人的身份证）
			
			if(objs!=null){
				tjm.setMchtCd(Constance.Null2EmptyTrim(objs[0]));
				tjm.setAccountName(Constance.Null2EmptyTrim(objs[1]));
				tjm.setAccount(Utils.dealCardNoTwo(Constance
						.Null2EmptyTrim(objs[2])));
				tjm.setBankName(Constance.Null2EmptyTrim(objs[3]));
				String cardNo = Constance.Null2EmptyTrim(objs[4]);
				String dvpBy = Constance.Null2EmptyTrim(objs[5]);
				if("1".equals(dvpBy)){//非法人结算
					cardNo = Constance.Null2EmptyTrim(objs[6]);//证件号
				}
				tjm.setCertifNo(cardNo);
				/*if (null != cardNo && cardNo.length() > 4) {
					tjm.setCertifNo(cardNo.substring(0, 3) + "****"
							+ cardNo.substring(cardNo.length() - 4));// 证件号
				} else {
					tjm.setCertifNo(cardNo);// 证件号
				}*/
			}
			
			
		} catch (Exception e) {
//			e.printStackTrace();
			logger.error("查询银行卡详情异常：",e);
			throw new ServiceException("查询银行卡详情异常",e);
		}
		
		return tjm;
	}
	
	@Transactional(rollbackFor = { ServiceException.class })
	@Override
	public synchronized Map<String,Object> saveFourEleForm(TblJumpMchtInf tjm,Operators logingMerchant) throws ServiceException {
		String inserSql = "insert into t_wechat_validate (ID, OPEN_ID, PHONE_NO, ACCOUNT_NO, ACCOUNT_NAME, "
				+ "IDENTITY_CARD, STATUS, CREATE_TIME, UPDATE_TIME, REMARK)"
				+"values (SEQ_WECHAT_VALIDATE.Nextval,?,?,?,?,?,?,?,?,?)";
		
		String selRiskLevelSql = "select 1 from apstfr.tbl_mgm_risk_level t where t.risk_num_type='card' and t.risk_num=? ";
		String insertRiskLevelSql = "insert into apstfr.tbl_mgm_risk_level (RISK_NUM, RISK_NUM_TYPE, RISK_LEVEL, REMARK1, REMARK2, REMARK3) "
									+"values (?, 'card', 'E', '', '', '')";
		
		String sql = "select a.mcht_cd,b.name,b.account,b.bank_name,a.certif_no,a.DVP_BY,a.STLM_WAY_DESC "
				+ "from tbl_mcht_inf a,tbl_mcht_bankaccount b "
				+ "where a.mcht_cd=b.owner_cd and b.accounttype='01' and a.status='01' and a.mcht_cd=? ";
		
		String selFourEleSql = "select 1 from t_wechat_validate t where t.phone_no=? and t.account_no=? and t.account_name=? and t.identity_card=? and t.open_id=? and t.remark='1' ";

		List<Object> paramsList = new ArrayList<Object>();
		Map<String,Object> resMap = new HashMap<String, Object>();
		try {
			
			String pho = Constance.Null2EmptyTrim(tjm.getContactPho());
			if("".equals(pho)){
				resMap.put("msg", "银行预留手机号码为空");
				return resMap;
			}
			
			String certifNo = Constance.Null2EmptyTrim(tjm.getCertifNo());
			if("".equals(certifNo)){
				resMap.put("msg", "结算人身份证号码为空");
				return resMap;
			}
			
			if(!CheckIdCard.iDCardValidate(certifNo)){
				resMap.put("msg", "结算人身份证号码格式错误");
				return resMap;
			}
			
			Object mchtObj = sqlBaseDao.findObj(sql, new Object[]{tjm.getMchtCd()});
			Object[] objs = (Object[]) mchtObj;
			
			String accountName = Constance.Null2EmptyTrim(objs[1]);
			String account = Constance.Null2EmptyTrim(objs[2]);
//			String bankName = Constance.Null2EmptyTrim(objs[3]);
			
			
			//DVP_BY	N	NVARCHAR2(50)	Y			发展人/推荐人 （ 0是  1否法人结算账户，若为否则需要非法人身份证号）
			//STLM_WAY_DESC	N	VARCHAR2(50)	Y			商户结算途径其它说明（非法人的身份证）
			String dvpBy = Constance.Null2EmptyTrim(objs[5]);
			
			
			Object selObj = sqlBaseDao.findObj(selFourEleSql, new Object[]{
					pho,
					account,
					accountName,
					certifNo,
					tjm.getMchtCd()
			});
			
			JSONObject jsonObject = new JSONObject();
			 jsonObject.put("type","four");
			 jsonObject.put("name",accountName);
			 jsonObject.put("citizenIdNumber",certifNo);
			 jsonObject.put("card",account);
			 jsonObject.put("phone",pho); 
			//银行卡验证
			String result = HttpUtil.sendGetOrPostR(Utils.getConfigValue("CREDIT_CK"), jsonObject.toString());
//			boolean result = FourElementValidateUtils.sendPayjnlsAuditOfJiean(tjm.getAccountName(), tjm.getCertifNo(), tjm.getAccount(), pho);
			JSONObject obj = JSONObject.parseObject(result);
			String msg_code = (String) obj.get("msg_code");
			if("00".equals(msg_code)){//判断验证的信息
            		List<Object> updlist = new ArrayList<Object>();
					String updateSql ="";
					if("1".equals(dvpBy)){//非法人结算
						updateSql =" UPDATE  tbl_mcht_inf  SET isgroup=?,K2WORKFLOWID=?,REC_UPD_TS=?,OPER_IN=?,STLM_WAY_DESC=? WHERE mcht_cd=? ";
						logger.info("自选商户开通商户【"+tjm.getMchtCd()+"】原非法人身份证号码【"+Constance.Null2EmptyTrim(objs[6])+"】修改为【"+certifNo+"】操作人："+logingMerchant.getAccountNo());
					}else{
						updateSql =" UPDATE  tbl_mcht_inf  SET isgroup=?,K2WORKFLOWID=?,REC_UPD_TS=?,OPER_IN=?,CERTIF_NO=? WHERE mcht_cd=? ";
						logger.info("自选商户开通商户【"+tjm.getMchtCd()+"】原法人身份证号码【"+Constance.Null2EmptyTrim(objs[4])+"】修改为【"+certifNo+"】操作人："+logingMerchant.getAccountNo());
					}
					
					updlist.add("B");
					updlist.add(pho);
					updlist.add(new Date());
					updlist.add("U");
					updlist.add(certifNo);
					updlist.add(tjm.getMchtCd());
					int updCount = sqlBaseDao.deleteBySql(updateSql, updlist);
					if(updCount != 1){
						throw new ServiceException("商户【"+tjm.getMchtCd()+"】银行卡验证成功后修改商户等级失败");
					}
					
					if(selObj == null){
						
					
						//保存银行卡验证信息
						paramsList.clear();
						paramsList.add(tjm.getMchtCd());
						paramsList.add(pho);
						paramsList.add(account);
						paramsList.add(accountName);
						paramsList.add(certifNo);
						paramsList.add("0");
						paramsList.add(new Date());
						paramsList.add("");
						paramsList.add("1");
						int insertFourEleCount = sqlBaseDao.deleteBySql(inserSql, paramsList);
						if(insertFourEleCount != 1){
							throw new ServiceException("商户【"+tjm.getMchtCd()+"】银行卡验证信息保存失败，操作人："+logingMerchant.getAccountNo());
						}
						
						logger.info("商户【"+tjm.getMchtCd()+"】银行卡验证信息保成功，操作人："+logingMerchant.getAccountNo());
					}
					
					Object objArray = sqlBaseDao.findObj(selRiskLevelSql, new Object[]{account});
					if(objArray == null){
						paramsList.clear();
						paramsList.add(account);
						int insertCount = sqlBaseDao.deleteBySql(insertRiskLevelSql, paramsList);
						if(insertCount != 1){
							throw new ServiceException("商户【"+tjm.getMchtCd()+"】卡号【"+account+"】RiskLevel保存成功，操作人："+logingMerchant.getAccountNo());
						}
					}
					
					resMap.put("msg", "银行卡验证成功");
					
			}else{
				resMap.put("msg", "银行卡验证失败");
				
			}
			
			
			
			return resMap;
		} catch (Exception e) {
			
			logger.error("商户【"+tjm.getMchtCd()+"】银行卡验证失败",e);
			throw new ServiceException("商户【"+tjm.getMchtCd()+"】银行卡验证失败，操作人："+logingMerchant.getAccountNo());
		}
		
		
	}
	
}
